/* 
 * File:   Thread.h
 * Author: flai0014
 *
 * Created on April 4, 2012, 3:03 PM
 */

#ifndef _THREAD_H
#define	_THREAD_H

#include <iostream>
#include <pthread.h>
#include <cassert>
#include <error.h>
#include <cstdlib>

using namespace std;


class Thread {
protected:
        /* Function called by the pthread_create function call */
	static void* startThread(void* pVoid){
            ((Thread*)pVoid)->run(pVoid);//Uses the run function
            return 0;
        }
        
        /* Standard error printing*/
	void printError(char * msg, int status, char* fncName, int lineNumber){
            cerr << msg << " " << fncName << ":" << lineNumber <<
                    "-" << status << endl;
        }
        
public:
	Thread() {}
	virtual ~Thread() {}
        
        /* This initializes the attributes and creates the thread to be run*/
	void start(){
            curThread = this;
            // initialize attribute object
            int status = pthread_attr_init(&threadAttribute);
            if(status) {
                    cerr << "pthread_attr_init failed at" << status <<
                            "start()" <<  __LINE__ ;
                    exit(status);
            }
            status = pthread_create(&PthreadThreadID, &threadAttribute,
                    Thread::startThread, ((void*)curThread));	
            if(status) {
                    cerr << "pthread_attr_init failed at" << status <<
                            "start()" <<  __LINE__ ;
                    exit(status);
            }
            status = pthread_attr_destroy(&threadAttribute);
            if(status) {
                    cerr << "pthread_attr_init failed at" << status <<
                            "start()" <<  __LINE__ ;
                    exit(status);
            }
        }
        virtual void stop() {}
        
        /* run function to be overridden by inheriting class */
	virtual void* run(void* attb) = 0;
private:
	// thread ID
	pthread_t PthreadThreadID;
	pthread_attr_t threadAttribute;
        Thread* curThread;
	Thread(const Thread&);
	const Thread& operator=(const Thread&);
	// called when run() completes
	void setCompleted() {}
	// stores return value from run()
	void* result;

};

#endif	/* THREAD_H */

